package io.gitee.loulan_yxq.owner.poi.excel.entity;

import io.gitee.loulan_yxq.owner.core.collection.CollTool;
import io.gitee.loulan_yxq.owner.core.map.MapTool;
import io.gitee.loulan_yxq.owner.core.tool.ObjectTool;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/*********************************************************
 ** excel导出配置
 ** <br><br>
 ** Date: Created in 2022/9/1 10:52
 ** @author loulan
 ** @version 0.0.0
 *********************************************************/
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelExportConfiguration {
    // 表名
    private String sheetName;
    // 表头显示配置
    private List<ExcelHeaderConfiguration> headerConfig;

    // 数据
    private List<?> data;
    // 数据开始行，也就是数据从第几行开始写
    private Integer dataStartRow;
    // 输出流
    private OutputStream outputStream;

    // 数据处理器
    private Function<Object, String> dataHandler;

    /*********************************************************
     ** 构建者类
     ** <br><br>
     ** Date: Created in 2022/9/1 17:37
     ** @author loulan
     ** @version 0.0.0
     *********************************************************/
    public static class Builder {
        // excel导出配置对象
        private ExcelExportConfiguration exportConfiguration;

        private Builder(ExcelExportConfiguration exportConfiguration) {
            this.exportConfiguration = exportConfiguration;
        }

        /**
         * 构建建造者对象
         *
         * @return 建造者对象
         * @author :loulan
         */
        public static Builder builder() {
            ExcelExportConfiguration excelExportConfiguration = new ExcelExportConfiguration();
            excelExportConfiguration.headerConfig = CollTool.list();
            return new Builder(excelExportConfiguration);
        }

        /**
         * 设置工作簿名称
         *
         * @param sheetName 工作簿名称
         * @return 构建者对象
         * @author :loulan
         */
        public Builder sheetName(String sheetName) {
            this.exportConfiguration.sheetName = sheetName;
            return this;
        }

        /**
         * 设置excel的输出流
         *
         * @param outputStream excel的输出流
         * @return 构建者对象
         * @author :loulan
         */
        public Builder outputStream(OutputStream outputStream) {
            this.exportConfiguration.outputStream = outputStream;
            return this;
        }

        /**
         * 添加表头配置
         *
         * @param headerConfiguration 表头配置对象
         * @return 构建者对象
         * @author :loulan
         */
        public Builder addHeader(ExcelHeaderConfiguration headerConfiguration) {
            this.exportConfiguration.getHeaderConfig().add(headerConfiguration);
            return this;
        }

        /**
         * 设置导出数据
         *
         * @param data     导出数据
         * @param startRow 从第几行开始写数据
         * @return 构建者对象
         * @author :loulan
         */
        public Builder data(List<?> data, Integer startRow) {
            this.exportConfiguration.data = data;
            this.exportConfiguration.dataStartRow = startRow;
            return this;
        }

        /**
         * 设置导出数据
         *
         * @param data 导出数据
         * @return 构建者对象
         * @author :loulan
         */
        public Builder data(List<?> data) {
            return data(data, null);
        }

        /**
         * 设置全局数据处理器，如果表头配置的数据处理器没有配置，那么就会执行这个数据处理器，所有写入excel的数据经过数据处理器处理之后才会写入excel
         * 全局处理器不能为null，所以在构建的时候会进行判断，如果不存在就设置一个默认的处理器。
         *
         * @param dataHandler 数据处理器对象
         * @return 构建者对象
         * @author :loulan
         */
        public Builder dataHandler(Function dataHandler) {
            this.exportConfiguration.dataHandler = dataHandler;
            return this;
        }

        /**
         * 构建Excel导出配置对象
         *
         * @return Excel导出配置对象
         * @author :loulan
         */
        public ExcelExportConfiguration build() {

            // 如果全局处理器不存在就默认一个处理器
            if (ObjectTool.isNull(this.exportConfiguration.dataHandler)) {
                this.exportConfiguration.dataHandler = obj -> ObjectTool.isNull(obj) ? "" : String.valueOf(obj);
            }

            return this.exportConfiguration;
        }
    }
}
